#ifndef MS3D_H
#define MS3D_H

//
// max values
//
#define MAX_VERTICES    65534
#define MAX_TRIANGLES   65534
#define MAX_GROUPS      255
#define MAX_MATERIALS   128
#define MAX_JOINTS      128


//
// flags
//
#define SELECTED        1
#define HIDDEN          2
#define SELECTED2       4
#define DIRTY           8


//
// types
//
#ifndef byte
typedef unsigned char byte;
#endif // byte

#ifndef word
typedef unsigned short word;
#endif // word

//
// First comes the header (sizeof(ms3d_header_t) == 14)
//
typedef struct
{
    char    id[10];                                     // always "MS3D000000"
    int     version;                                    // 4
}  __attribute__ ((__packed__)) ms3d_header_t;

//
// Then come nNumVertices times ms3d_vertex_t structs (sizeof(ms3d_vertex_t) == 15)
//
typedef struct
{
    byte    flags;                                      // SELECTED | SELECTED2 | HIDDEN
    float   vertex[3];                                  //
    char    boneId;                                     // -1 = no bone
    byte    referenceCount;
} __attribute__ ((__packed__)) ms3d_vertex_t;

//
// Then come nNumTriangles times ms3d_triangle_t structs (sizeof(ms3d_triangle_t) == 70)
//
typedef struct
{
    word    flags;                                      // SELECTED | SELECTED2 | HIDDEN
    word    vertexIndices[3];                           //
    float   vertexNormals[3][3];                        //
    float   s[3];                                       //
    float   t[3];                                       //
    byte    smoothingGroup;                             // 1 - 32
    byte    groupIndex;                                 //
} __attribute__ ((__packed__)) ms3d_triangle_t;

#define GROUP_INFO \
    byte flags; \
    char name[32]; \
    word numtriangles;


//
// Then come nNumGroups times groups (the sizeof a group is dynamic, because of triangleIndices is numtriangles long)
//
typedef struct
{
    GROUP_INFO
    word            *triangleIndices;      // the groups group the triangles
    char            materialIndex;                      // -1 = no material
} __attribute__ ((__packed__)) ms3d_group_t;

//
// Then come nNumMaterials times ms3d_material_t structs (sizeof(ms3d_material_t) == 361)
//
typedef struct
{
    char            name[32];                           //
    float           ambient[4];                         //
    float           diffuse[4];                         //
    float           specular[4];                        //
    float           emissive[4];                        //
    float           shininess;                          // 0.0f - 128.0f
    float           transparency;                       // 0.0f - 1.0f
    char            mode;                               // 0, 1, 2 is unused now
    char            texture[128];                        // texture.bmp
    char            alphamap[128];                       // alpha.bmp
} __attribute__ ((__packed__)) ms3d_material_t;

typedef struct
{
    float fAnimationFPS; // 4 bytes
    float fCurrentTime; // 4 bytes
    int iTotalFrames; // 4 bytes
} __attribute__ ((__packed__)) ms3d_anim_info_t;

//
// Then come nNumJoints joints (the size of joints are dynamic, because each joint has a differnt count of keys
//
typedef struct // 16 bytes
{
    float           time;                               // time in seconds
    float           rotation[3];                        // x, y, z angles
} __attribute__ ((__packed__)) ms3d_keyframe_rot_t;

typedef struct // 16 bytes
{
    float           time;                               // time in seconds
    float           position[3];                        // local position
} __attribute__ ((__packed__)) ms3d_keyframe_pos_t;

#define JOINT_INFO \
    byte flags; \
    char name[32]; \
    char parentName[32]; \
    float rotation[3]; \
    float position[3]; \
    word numKeyFramesRot; \
    word numKeyFramesTrans;

typedef struct
{
    JOINT_INFO

    ms3d_keyframe_rot_t *keyFramesRot;      // local animation matrices
    ms3d_keyframe_pos_t *keyFramesTrans;  // local animation matrices
} __attribute__ ((__packed__)) ms3d_joint_t;

#endif

